package com.siyoumi.component;

import com.alibaba.fastjson.JSON;
import com.siyoumi.service.SysLogService;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XStr;
import com.siyoumi.validator.XValidator;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;

//log流水线
@Slf4j
public class LogPipeLine {
    //线程对象
    static final private ThreadLocal<LogPipeLine> tl = new ThreadLocal<>();

    static public LogPipeLine getTl() {
        return getInstance();
    }

    static public LogPipeLine getInstance() {
        //同一个线程，只会new 1次
        LogPipeLine util = tl.get();
        if (util != null) {
            return util;
        }

        util = new LogPipeLine();
        tl.set(util);
        return util;
    }


    private List<String> logMsgList = new ArrayList<>();
    private LocalDateTime lastTime;
    private Map<String, Object> mapAppend = new HashMap<>(); //追加参数


    public void tlRemove() {
        tl.remove();
    }

    public void clear() {
        logMsgList = new ArrayList<>();
    }

    /**
     * 记录日志
     *
     * @param method
     * @param siteId
     */
    public void saveDb(String method, String siteId) {
        String msg = getLogMsg();
        //释放对象
        tlRemove();
        //
        if (XStr.isNullOrEmpty(msg)) {
            log.debug("日志内容为空，不插入数据");
            return;
        }

        if (mapAppend == null) {
            mapAppend = new HashMap<>();
        }
        String logStr00 = (String) mapAppend.get("log_str_00");
        String logStr01 = (String) mapAppend.get("log_str_01");

        //Boolean queue = true; //redis延迟插入
        //if (Helper.funcIsDev()) {
        //    queue = false;
        //}

        SysLogService.getBean().addSysLog("log", logStr00, msg, logStr01);
    }

    /**
     * 获取步骤文字
     *
     * @return string
     */
    public String getLogMsg() {
        StringBuilder str = new StringBuilder();
        int index = 1;//序号
        for (String msg : this.logMsgList) {
            str.append(index).append("：").append(msg).append(System.getProperty("line.separator"));
            index++;
        }

        return str.toString();
    }

    /**
     * 方法名称
     *
     * @param funName
     */
    public void setFunName(String funName) {
        setAppendData("log_str_00", funName);
    }

    /**
     * 追加参数
     *
     * @param key
     * @param val
     */
    public void setAppendData(String key, String val) {
        String[] keys = {
                //"log_wxuser_id",
                //"log_id_src",
                "log_str_00",
                "log_str_01",
                //"log_str_02",
                //"log_str_03",
        };
        List<String> keyArr = Arrays.asList(keys);
        if (!keyArr.contains(key)) {
            XValidator.err(20098, "key error");
        }

        mapAppend.put(key, val);
    }

    public void setLogMsg(String... msg) {
        setLogMsg(XStr.concat(msg));
    }

    public void setLogMsgFormat(String msg, String... args) {
        setLogMsg(XStr.format(msg, args));
    }

    /**
     * 步骤文字记录
     *
     * @param msg
     */
    public void setLogMsg(Object msg) {
        String logMsg = "";
        if (msg instanceof String) {
            logMsg = (String) msg;
        } else {
            logMsg = JSON.toJSONString(msg);
        }

        LocalDateTime now = LocalDateTime.now();//时间
        int t_ms = 0;//离上步骤-相差多少毫秒

        if (this.lastTime != null) {
            Duration duration = Duration.between(this.lastTime, now);
            t_ms = Integer.parseInt(String.valueOf(duration.toMillis()));
        }

        //[2023-07-04 09:58:55] [0ms] testabc
        logMsg = "[" + XDate.toDateTimeString(now) + "] [" + t_ms + "ms] " + logMsg;
        this.logMsgList.add(logMsg);
        this.lastTime = now;
        log.info(logMsg);
    }


}
